package Task28;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

public class CommandFactory {

	private Map<String, Constructor<?>> mapOfCommandClasses;
	private Map<String, CommandInterface> mapOfCommandInstance;
	private boolean mapCreated = false;

	public void createMap() throws SecurityException, NoSuchMethodException,
			IllegalArgumentException, IllegalAccessException,
			NoSuchFieldException, InstantiationException,
			InvocationTargetException {
		if (!mapCreated) {
			mapCreated = true;
			mapOfCommandClasses = new HashMap<String, Constructor<?>>();
			mapOfCommandInstance = new HashMap<String, CommandInterface>();

			for (Class<?> subclass : new Model().getClass().getClasses()) {
				Constructor<?> constructor = subclass
						.getDeclaredConstructor(Model.class);

				constructor.setAccessible(true);

				String key = (String) constructor.newInstance(new Model())
						.getClass().getDeclaredField("id").get(null);
				mapOfCommandClasses.put(key, constructor);
				mapOfCommandInstance.put(key, null);
			}
		}
	}

	public CommandInterface getCommandInstance(String command)
			throws IllegalArgumentException, InstantiationException,
			IllegalAccessException, InvocationTargetException,
			SecurityException, NoSuchMethodException, NoSuchFieldException {

		CommandInterface result;
		if (mapOfCommandInstance.get(command) == null) {
			CommandInterface instance = (CommandInterface) mapOfCommandClasses
					.get(command).newInstance(new Model());
			result = instance;
			mapOfCommandInstance.put(command, instance);
		} else {
			result = mapOfCommandInstance.get(command);
		}
		return result;
	}

	public boolean containsId(String id) {
		boolean bResult = false;
		if (mapCreated)
			bResult = mapOfCommandClasses.containsKey(id);
		return bResult;
	}

	}
